package com.wctj.api.business.common.helper;

import com.wctj.api.base.enums.ApiCode;
import com.wctj.api.base.enums.EventTypeEnums;
import com.wctj.api.base.enums.PayModeEnums;
import com.wctj.api.base.exception.CustomException;
import com.wctj.api.business.common.service.PayResponse;
import com.wctj.api.business.common.service.handler.CmbAbstractEventTypeResponse;
import com.wctj.api.business.common.service.handler.HuiFuAbstractEventTypeResponse;
import com.wctj.api.infra.common.bean.NoticeParams;
import com.wctj.api.infra.web.support.HttpRequestNoticeParams;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

/**
 * 支付回调响应模式处理
 */
@Slf4j
@Component
public class PayResponseHelper implements BeanPostProcessor {

    /**
     * 按照类型分发
     */
    private Map<PayModeEnums, PayResponse> payResponseMap = new HashMap<>();
    // 根据汇付不同渠道的事件类型进行分发
    private Map<String, HuiFuAbstractEventTypeResponse> huiFuEventTypeMap =  new HashMap<String, HuiFuAbstractEventTypeResponse>(10);
    // 根据招行不同渠道的事件类型进行分发
    private Map<String, CmbAbstractEventTypeResponse> cmbEventTypeMap =  new HashMap<String, CmbAbstractEventTypeResponse>(5);


    /**
     * 分发支付场景整合
     * @param noticeParams
     * @param payMode  cmb_letuu   cmb_zgzg
     */
    public String handle(HttpRequestNoticeParams noticeParams, String payMode) {
        PayModeEnums modeEnums = PayModeEnums.of(payMode.split("_")[0]);
        PayResponse payResponseService = payResponseMap.get(modeEnums);
        if (Objects.isNull(payResponseService)){
            throw new CustomException(ApiCode.PAY_MODEL_NOT_EXIST_FAIL);
        }
        log.info("handle serviceName:{},{}",payResponseService.getClass().getSimpleName(),payMode);
        return payResponseMap.get(modeEnums).handle(noticeParams,payMode);
    }


    /**
     * 汇付分发事件类型场景
     * @param eventType eg: payment.succeeded，payment.fail
     * @param eventType
     */
    public String eventTypeHuiFuHandle(HttpRequestNoticeParams noticeParams, String eventType) {
        EventTypeEnums typeEnums = EventTypeEnums.of(eventType);
        HuiFuAbstractEventTypeResponse eventTypeResponse = huiFuEventTypeMap.get(typeEnums.getType());
        log.info("eventTypeHuiFuHandle serviceName:{},{}",eventTypeResponse.getClass().getSimpleName(),eventType);
        if (Objects.isNull(eventTypeResponse)){
            throw new CustomException(ApiCode.PAY_EVENT_TYPE_NOT_EXIST_FAIL);
        }
        return eventTypeResponse.businessHandle(noticeParams);
    }

    /**
     * CMB分发事件类型场景
     * @param eventType eg: payment.succeeded，payment.fail
     * @param eventType
     */
    public String eventTypeCmbHandle(NoticeParams noticeParams, String eventType) {
        EventTypeEnums typeEnums = EventTypeEnums.of(eventType);
        CmbAbstractEventTypeResponse eventTypeResponse = cmbEventTypeMap.get(typeEnums.getType());
        log.info("eventTypeCmbHandle serviceName:{},{}",eventTypeResponse.getClass().getSimpleName(),eventType);
        if (Objects.isNull(eventTypeResponse)){
            throw new CustomException(ApiCode.PAY_EVENT_TYPE_NOT_EXIST_FAIL);
        }
        return eventTypeResponse.businessHandle(noticeParams);
    }

    /**
     * 添加后置处理，把 bean 收集到 map
     *
     * @param bean
     * @param beanName
     * @return
     * @throws BeansException
     */
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if (bean instanceof PayResponse) {
            PayResponse payResponse = (PayResponse) bean;
            payResponseMap.put(payResponse.getPayMode(),payResponse);
        }

        if (bean instanceof HuiFuAbstractEventTypeResponse) {
            HuiFuAbstractEventTypeResponse eventTypeResponse = (HuiFuAbstractEventTypeResponse) bean;
            huiFuEventTypeMap.put(eventTypeResponse.getEventType(),eventTypeResponse);
        }

        if (bean instanceof CmbAbstractEventTypeResponse) {
            CmbAbstractEventTypeResponse eventTypeResponse = (CmbAbstractEventTypeResponse) bean;
            cmbEventTypeMap.put(eventTypeResponse.getEventType(),eventTypeResponse);
        }
        return bean;
    }


}
